%include "pm.inc"

org 	07c00h
	jmp 	LABEL_BEGIN

[section .gdt]
LABEL_GDT:			Descriptor 		0,0,0	;空描述符
LABEL_DESC_CODE32: 	Descriptor 		0,SegCode32Len-1,DA_C+DA_32		;非一致代码段
LABEL_DESC_VIDEO:	Descriptor 		0b8000h,0ffffh,DA_DRW	;显存首地址

GdtLen		equ 	$-LABEL_GDT		;gdt长度
GdtPtr		equ 	GdtLen-1		;GDT界限
			dd		0				;GDT基址
			
;GDT选择子
SelectorCode32 		equ		LABEL_DESC_CODE32-LABEL_GDT
selectorVideo		equ		LABEL_DESC_VIDEO-LABEL_GDT

[section .s16]									;实模式向保护模式跳转
[bits 16]
LABEL_BEGIN:
	mov 	ax,cs								;把所有段寄存器都指向代码段
	mov 	ds,ax
	mov 	es,ax
	mov 	ss,ax
	mov 	sp,0100h
	
	;初始化32位代码段描述符						让其指向LABEL_SEG_CODE32
	xor 	eax,eax		;eax清零
	mov 	ax,cs
	shl 	eax,4
	add 	eax,LABEL_SEG_CODE32
	mov 	word[LABEL_DESC_CODE32+2],ax		;设定s32的GDT的内容
	shr		eax,16
	mov 	byte[LABEL_DESC_CODE32+4],al
	mov 	byte[LABEL_DESC_CODE32+7],ah
	
	;为加载GDTR作准备GDTR(48位)=32位基地址+16位界限
	xor 	eax,eax
	mov 	ax,ds								
	shl 	eax,4
	add 	eax,LABEL_GDT
	mov 	dword[GdtPtr+2],eax					;让GdtPtr的GDT指向LABEL_GDT
	
	;加载GDTR
	lgdt 	[GdtPtr]
	
	cli		;关中断
	
	;打开A20
	in 		al,92h
	or 		al,00000010b
	out 	92h,al
	
	;准备切换到保护模式
	mov 	eax,cr0
	or 		eax,1
	mov		cr0,eax
	
	;进入保护模式
	jmp		dword SelectorCode32:0			;把SelectorCode32装入cs,并跳转到SelectorCode32:0
	
[section .s32]
[bits 32]
LABEL_SEG_CODE32:
	mov 	ax,selectorVideo
	mov 	gs,ax
	
	mov 	edi,(80*11+79)*2				;屏幕第11行79列
	mov 	ah,0ch							;0000:黑底		1100:红字
	mov		al,'p'
	mov 	[gs:edi],ax
	mov 	al,'l'
	mov 	edi,(80*11+77)*2
	mov 	[gs:edi],ax
	
	jmp		$

SegCode32Len 	equ 	$-LABEL_SEG_CODE32
	
	
	
	
	
